
<script lang="ts">
import { useUser } from '@/store';
import * as api from "@/api";
import { I_PersonRes } from '@/types';
import type { FormInstance, FormRules, TableColumnCtx } from 'element-plus';
import { useExcelExport } from '@/hooks';
interface I_State {
    userList: I_PersonRes[];
    isOpenChangeInfoDialog: boolean;
    isOpenAddUserDialog: boolean;
    isOpenImportDialog: boolean;
    tempForm: I_PersonRes | null;
    search: string;
    isOpenExportDialog: boolean;
    pages: {
        currentPage: number;
        pageSize: number;
        total: number;
    };
    exportParams: { institute?: string, major?: string; cls?: string; role?: string; };
}
export default defineComponent({
    setup() {
        const userStore = useUser();
        const { user } = storeToRefs(userStore);
        const router = useRouter();
        const state = reactive<I_State>({
            userList: [],
            isOpenChangeInfoDialog: false,
            tempForm: {
                address: "",
                cls: "",
                id: 0,
                institute: "",
                major: "",
                name: "",
                password: "",
                phone: "",
                role: "",
                sex: "",
                uid: "",
            },
            search: "",
            pages: {
                currentPage: 1,
                pageSize: 10,
                total: 10,
            },
            exportParams: {
                institute: "",
                major: "",
                cls: "",
                role: ""
            },
            isOpenAddUserDialog: false,
            isOpenExportDialog: false,
            isOpenImportDialog: false
        });
        const addFormRef = ref<FormInstance>();
        const ruleFormRef = ref<FormInstance>();
        const uploadRef = ref<any>();
        const frozenData = {
            institutes: {
                '计算机科学与技术学院': {
                    '软件': [
                        ...Array(9).fill(0).map((_, index) => '软件200' + (index + 1)),
                    ],
                    '计科': [
                        ...Array(9).fill(0).map((_, index) => '计科200' + (index + 1)),
                    ],
                    '信安': [
                        ...Array(9).fill(0).map((_, index) => '信安200' + (index + 1)),
                    ],
                },
                '法学院': {
                    '法学': [
                        ...Array(9).fill(0).map((_, index) => '法学200' + (index + 1)),
                    ],
                },
                '马克思学院': {
                    '马克思学': [
                        ...Array(9).fill(0).map((_, index) => '马克思200' + (index + 1)),
                    ],
                }
            },
        };
        onMounted(() => {
            api.user.getAllUserInformation({ index: state.pages.currentPage, size: state.pages.pageSize }).then(res => {
                state.pages.total = res.total;
                state.userList = res.records;
            }).catch(err => {
                router.replace('/login');
            });
        });
        let timer: any;
        watch([() => state.search], () => {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
            timer = setTimeout(() => {
                api.user.getPersonData({ search: state.search, index: state.pages.currentPage, size: state.pages.pageSize }).then(res => {
                    state.userList = res.records;
                    state.pages.total = res.total;
                });
                timer = null;
            }, 500);
        });
        const deletePerson = (data: I_PersonRes) => {
            api.user.deleteUserInformation({ id: data.id }).then(_ => {
                api.user.getAllUserInformation({ index: state.pages.currentPage, size: state.pages.pageSize }).then(res => {
                    state.pages.total = res.total;
                    state.userList = res.records;
                });
            }).catch(_ => {
            });
        };
        const updatePerson = async (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            await formEl.validate((valid, fields) => {
                if (valid) {
                    api.user.updatePersonInformation(state.tempForm as I_PersonRes).then(res => {
                        closeChangeInfoDialog();
                        api.user.getPersonData({ search: state.search, index: state.pages.currentPage, size: state.pages.pageSize }).then(res => {
                            state.userList = res.records;
                            state.pages.total = res.total;
                        }).catch(err => {
                            router.replace('/login');
                        });
                    }).catch(err => {
                        router.replace('/login');
                    });
                }
            });
        };
        const phoneValidator = (rule: any, value: any, callback: any) => {
            if (!value) {
                return callback(new Error('请输入手机号'));
            } else {
                const reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/;
                if (!reg.test(value)) {
                    callback(new Error('请输入正确的手机号'));
                } else {
                    callback();
                }
            }
        };
        const personRules = reactive<FormRules>({
            uid: [
                { required: true, message: "请输入用户名", trigger: "blur" },
                { min: 3, max: 16, message: "长度在 3 到 12 个字符", trigger: "blur" },
            ],
            name: [
                { required: true, message: "请输入姓名", trigger: "blur" },
                { min: 2, max: 10, message: "长度在 2 到 10 个字符", trigger: "blur" },
            ],
            sex: [
                { required: true, message: '请选择性别', trigger: 'change', },
            ],
            address: [
                { required: true, message: "请输入地址", trigger: "blur" },
                { min: 3, max: 50, message: "长度在 3 到 50 个字符", trigger: "blur" },
            ],
            institute: [
                { required: true, message: '请选择学院', trigger: 'change', },
            ],
            major: [
                { required: true, message: '请选择专业', trigger: 'change', },
            ],
            cls: [
                { required: true, message: '请选择班级', trigger: 'change', },
            ],
            role: [
                { required: true, message: '请选择角色', trigger: 'change', },
            ],
            phone: [
                { required: true, message: "请输入手机号", trigger: "blur" },
                { validator: phoneValidator, trigger: "blur" },
            ],

            password: [
                { required: true, message: "请输入密码", trigger: "blur" },
                { min: 3, max: 16, message: "长度在 3 到 16 个字符", trigger: "blur" },
            ],
        });
        const filterHandler = (value: string, row: I_PersonRes, column: TableColumnCtx<I_PersonRes>) => (row as any)[column['property']] === value;
        const openChangeInfoDialog = (data: I_PersonRes) => {
            state.tempForm = { ...data };
            state.isOpenChangeInfoDialog = true;
            state.tempForm.password = "";
        };
        const closeChangeInfoDialog = () => {
            state.isOpenChangeInfoDialog = false;
            state.tempForm = {
                address: "",
                cls: "",
                id: 0,
                institute: "",
                major: "",
                name: "",
                password: "",
                phone: "",
                role: "",
                sex: "",
                uid: "",
            };
        };
        const closeAddInfoDialog = () => {
            state.isOpenAddUserDialog = false;
            state.tempForm = {
                address: "",
                cls: "",
                id: 0,
                institute: "",
                major: "",
                name: "",
                password: "",
                phone: "",
                role: "",
                sex: "",
                uid: "",
            };
        };
        const openAddInfoDialog = () => {
            state.isOpenAddUserDialog = true;
            state.tempForm = {
                address: "",
                cls: "",
                id: 0,
                institute: "",
                major: "",
                name: "",
                password: "",
                phone: "",
                role: "",
                sex: "",
                uid: "",
            };
        };
        const handleCurrentChange = (val: number) => {
            state.pages.currentPage = val;
            api.user.getPersonData({ search: state.search, index: state.pages.currentPage, size: state.pages.pageSize }).then(res => {
                state.userList = res.records;
                state.pages.total = res.total;
            });
        };
        const handleSizeChange = (val: number) => {
            state.pages.pageSize = val;
            api.user.getPersonData({ search: state.search, index: state.pages.currentPage, size: state.pages.pageSize }).then(res => {
                state.userList = res.records;
                state.pages.total = res.total;
            });
        };
        const addPerson = async (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            await formEl.validate((valid, fields) => {
                if (valid) {
                    api.user.addPersonData(state.tempForm as I_PersonRes).then(res => {
                        closeAddInfoDialog();
                        api.user.getAllUserInformation({ index: state.pages.currentPage, size: state.pages.pageSize }).then(res => {
                            state.userList = res.records;
                            state.pages.total = res.total;
                        }).catch(err => {
                            router.replace('/login');
                        });
                    });
                }
            });
        };
        const openImportDialog = () => {
            state.isOpenImportDialog = true;
        };
        const closeImportDialog = () => {
            state.isOpenImportDialog = false;
        };
        const openExportDialog = () => {
            state.isOpenExportDialog = true;
            state.exportParams = {
                institute: "",
                major: "",
                cls: "",
                role: ""
            };
        };
        const closeExportDialog = () => {
            state.isOpenExportDialog = false;
            state.exportParams = {
                institute: "",
                major: "",
                cls: "",
                role: ""
            };
        };
        const importExcelProgress = (_: any, data: any): any => {
            if (!data) { // 若未选择文件
                return ElMessage.error("请选择文件再进行上传！");
            }
            if (!/.(xlsx|xlsx)$/i.test(data.name)) {
                uploadRef.value.clearFiles();
                return ElMessage.error("格式错误!");
            }
            if (data.size > 1024 * 9 * 1024) {
                uploadRef.value.clearFiles();
                return ElMessage.error("超出大小限制!");
            }
        };
        const importExcelSuccess = (data: any): any => {
            ElMessage.error(data.msg);
            api.user.getAllUserInformation({ index: state.pages.currentPage, size: state.pages.pageSize }).then(res => {
                state.pages.total = res.total;
                state.userList = res.records;
            }).catch(err => {
                router.replace('/login');
            });
        };
        const ExportJson = () => {
            api.user.exportPersonData(state.exportParams).then(res => {
                const head = {
                    uid: "学号",
                    name: "姓名",
                    sex: "性别",
                    institute: "学院",
                    major: "专业",
                    cls: "班级",
                    role: "身份",
                };
                useExcelExport([head, ...res.map((item: any) => {
                    const { id, phone, address, ...data } = item;
                    return data;
                }) as any], '用户信息', '表一');
                closeExportDialog();
            });
        };
        return {
            user,
            deletePerson,
            updatePerson,
            openChangeInfoDialog,
            filterHandler,
            closeChangeInfoDialog,
            closeAddInfoDialog,
            openAddInfoDialog,
            openExportDialog,
            closeImportDialog,
            closeExportDialog,
            addPerson,
            personRules,
            ruleFormRef,
            handleCurrentChange,
            ExportJson,
            addFormRef,
            uploadRef,
            handleSizeChange,
            openImportDialog,
            importExcelProgress,
            importExcelSuccess,
            frozenData,
            ...toRefs(state)
        };
    }
});
</script>
<template>
    <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item :to="{ name: 'r_welcome' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>系统管理</el-breadcrumb-item>
        <el-breadcrumb-item>用户管理</el-breadcrumb-item>
    </el-breadcrumb>
    <el-card style="overflow: auto">
        <el-table :data="userList" stripe style="width: 100%">
            <el-table-column fixed prop="uid" label="用户名" width="120" align="center" />
            <el-table-column fixed prop="name" label="姓名" width="80" align="center" />
            <el-table-column prop="sex" label="性别" width="60" align="center" />
            <el-table-column prop="role" label="角色" width="80" :filters="[
            { value: '教师', text: '教师' }, { value: '学生', text: '学生' }]" :filter-method="filterHandler" align="center" />
            <el-table-column prop="address" label="地址" width="200" align="center" />
            <el-table-column prop="institute" label="学院" width="220" align="center" />
            <el-table-column prop="cls" label="班级" width="120" align="center" />
            <el-table-column prop="major" label="专业" width="120" align="center" />
            <el-table-column prop="phone" label="手机号" width="120" align="center" />
            <el-table-column fixed="right" label="操作" width="220" align="center">
                <template #header>
                    <el-input v-model="search" size="large" placeholder="请输入姓名或学工号..." clearable />
                </template>
                <template #default="scope">
                    <el-button link type="primary" size="small" @click="openChangeInfoDialog(scope.row)">修改</el-button>
                    <el-button link type="primary" size="small" @click="deletePerson(scope.row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-row style="margin-top:10px;">
            <el-col :span="18">
                <el-pagination background layout="total,sizes,prev, pager, next" :total="pages.total"
                    :page-sizes="[3, 5, 10, 20]" :page-size="pages.pageSize" @size-change="handleSizeChange"
                    :current-page="pages.currentPage" @current-change="handleCurrentChange"></el-pagination>
            </el-col>
            <el-col :span="2">
                <el-button type="info" style="float:right;" @click="openImportDialog">导入</el-button>
            </el-col>
            <el-col :span="2">
                <el-button type="info" style="float:right;" @click="openExportDialog">导出</el-button>
            </el-col>
            <el-col :span="2">
                <el-button type="primary" style="float:right;" @click="openAddInfoDialog">新增</el-button>
            </el-col>
        </el-row>
    </el-card>
    <el-dialog v-model="isOpenChangeInfoDialog" :title="`更新用户信息(当前角色:${user.role})`">
        <el-form :model="tempForm!" ref="ruleFormRef" :rules="personRules">
            <el-form-item label="用户名" prop="uid" :label-width="100">
                <el-input v-model="tempForm!.uid" clearable placeholder="请输入用户名" />
            </el-form-item>
            <el-form-item label="姓名" prop="name" :label-width="100">
                <el-input v-model="tempForm!.name" clearable placeholder="请输入姓名" />
            </el-form-item>
            <el-form-item label="性别" prop="sex" :label-width="100" :required="isOpenChangeInfoDialog ? true : false">
                <el-select v-model="tempForm!.sex" placeholder="请选择性别" clearable>
                    <el-option label="男" value="男" />
                    <el-option label="女" value="女" />
                </el-select>
            </el-form-item>
            <el-form-item label="地址" prop="address" :label-width="100">
                <el-input v-model="tempForm!.address" clearable placeholder="请输入地址" />
            </el-form-item>
            <el-form-item label="学院" prop="institute" :label-width="100"
                :required="isOpenChangeInfoDialog ? true : false">
                <el-select v-model="tempForm!.institute" placeholder="请选择学院" clearable @change="tempForm!.major = ''">
                    <el-option :label="index" :value="index" v-for="(item, index) in     frozenData.institutes"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="专业" prop="major" :label-width="100" :required="isOpenChangeInfoDialog ? true : false">
                <el-select v-model="tempForm!.major" placeholder="请选择专业" clearable @change="tempForm!.cls = ''">
                    <el-option :label="index" :value="index"
                        v-for="(item, index) in     tempForm!.institute ? (frozenData.institutes as any)[tempForm!.institute] : []"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="班级" prop="cls" :label-width="100" :required="isOpenChangeInfoDialog ? true : false">
                <el-select v-model="tempForm!.cls" placeholder="请选择班级" clearable>
                    <el-option :label="item" :value="item"
                        v-for="(item, index) in     tempForm!.major ? (frozenData.institutes as any)[tempForm!.institute][tempForm!.major] : []"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="角色" prop="role" :label-width="100" :required="isOpenChangeInfoDialog ? true : false">
                <el-select v-model="tempForm!.role" placeholder="请选择角色" clearable>
                    <el-option :label="item" :value="item" v-for="(item, index) in     ['管理员', '教师', '学生']"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="手机号" prop="phone" :label-width="100">
                <el-input v-model="tempForm!.phone" clearable placeholder="请输入手机号" />
            </el-form-item>

            <el-form-item label="密码" prop="password" :label-width="100">
                <el-input v-model="tempForm!.password" show-password clearable placeholder="请输入密码" />
            </el-form-item>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="closeChangeInfoDialog">取消</el-button>
                <el-button type="primary" @click="updatePerson(ruleFormRef)">
                    更新
                </el-button>
            </span>
        </template>
    </el-dialog>
    <!-- 添加 -->
    <el-dialog v-model="isOpenAddUserDialog" :title="`新增用户(当前角色:${user.role})`">
        <el-form :model="tempForm!" ref="addFormRef" :rules="personRules">
            <el-form-item label="用户名" prop="uid" :label-width="100">
                <el-input v-model="tempForm!.uid" clearable placeholder="请输入用户名" />
            </el-form-item>
            <el-form-item label="姓名" prop="name" :label-width="100">
                <el-input v-model="tempForm!.name" clearable placeholder="请输入姓名" />
            </el-form-item>
            <el-form-item label="性别" prop="sex" :label-width="100" :required="isOpenAddUserDialog ? true : false">
                <el-select v-model="tempForm!.sex" placeholder="请选择性别" clearable>
                    <el-option label="男" value="男" />
                    <el-option label="女" value="女" />
                </el-select>
            </el-form-item>
            <el-form-item label="地址" prop="address" :label-width="100">
                <el-input v-model="tempForm!.address" clearable placeholder="请输入地址" />
            </el-form-item>
            <el-form-item label="学院" prop="institute" :label-width="100" :required="isOpenAddUserDialog ? true : false">
                <el-select v-model="tempForm!.institute" placeholder="请选择学院" clearable @change="tempForm!.major = ''">
                    <el-option :label="index" :value="index" v-for="(item, index) in frozenData.institutes"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="专业" prop="major" :label-width="100" :required="isOpenAddUserDialog ? true : false">
                <el-select v-model="tempForm!.major" placeholder="请选择专业" clearable @change="tempForm!.cls = ''">
                    <el-option :label="index" :value="index"
                        v-for="(item, index) in     tempForm!.institute ? (frozenData.institutes as any)[tempForm!.institute] : []"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="班级" prop="cls" :label-width="100" :required="isOpenAddUserDialog ? true : false">
                <el-select v-model="tempForm!.cls" placeholder="请选择班级" clearable>
                    <el-option :label="item" :value="item"
                        v-for="(item, index) in     tempForm!.major ? (frozenData.institutes as any)[tempForm!.institute][tempForm!.major] : []"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="角色" prop="role" :label-width="100" :required="isOpenAddUserDialog ? true : false">
                <el-select v-model="tempForm!.role" placeholder="请选择角色" clearable>
                    <el-option :label="item" :value="item" v-for="(item, index) in     ['管理员', '教师', '学生']"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="手机号" prop="phone" :label-width="100">
                <el-input v-model="tempForm!.phone" clearable placeholder="请输入手机号" />
            </el-form-item>
            <el-form-item label="密码" :label-width="100">
                <el-input v-model="tempForm!.password" show-password clearable placeholder="请输入密码(可为空)" />
            </el-form-item>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="closeAddInfoDialog">取消</el-button>
                <el-button type="primary" @click="addPerson(addFormRef)">
                    添加
                </el-button>
            </span>
        </template>
    </el-dialog>
    <!-- 导出 -->
    <el-dialog v-model="isOpenExportDialog" :title="`导出(当前角色:${user.role})`">
        <el-form :model="exportParams" :rules="personRules">
            <el-form-item label="学院" :label-width="100" :required="isOpenAddUserDialog ? true : false">
                <el-select v-model="exportParams!.institute" placeholder="请选择学院" clearable
                    @change="exportParams!.major = ''">
                    <el-option :label="index" :value="index" v-for="(item, index) in frozenData.institutes"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="专业" :label-width="100" :required="isOpenAddUserDialog ? true : false">
                <el-select v-model="exportParams!.major" placeholder="请选择专业" clearable @change="exportParams!.cls = ''">
                    <el-option :label="index" :value="index"
                        v-for="(item, index) in  exportParams!.institute ? (frozenData.institutes as any)[exportParams!.institute] : []"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="班级" :label-width="100" :required="isOpenAddUserDialog ? true : false">
                <el-select v-model="exportParams!.cls" placeholder="请选择班级" clearable>
                    <el-option :label="item" :value="item"
                        v-for="(item, index) in  exportParams!.major && exportParams!.institute ? (frozenData.institutes as any)[exportParams!.institute][exportParams!.major] : []"
                        :key="index" />
                </el-select>
            </el-form-item>
            <el-form-item label="角色" :label-width="100" :required="isOpenAddUserDialog ? true : false">
                <el-select v-model="exportParams!.role" placeholder="请选择角色" clearable>
                    <el-option :label="item" :value="item" v-for="(item, index) in  ['管理员', '教师', '学生']" :key="index" />
                </el-select>
            </el-form-item>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="closeExportDialog">取消</el-button>
                <el-button type="primary" @click="ExportJson()">
                    导出
                </el-button>

            </span>
        </template>
    </el-dialog>
    <el-dialog title="上传Excel文件" v-model="isOpenImportDialog" @close="closeImportDialog" width="30%">
        <el-upload drag ref="uploadRef" action="http://d98xa3.natappfree.cc/user/import" multiple
            :on-progress="importExcelProgress" :on-success="importExcelSuccess">
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
            <template #tip>
                <div class="el-upload__tip">
                    上传文件吧
                </div>
            </template>
        </el-upload>
    </el-dialog>
</template>
<style lang = "less" scoped>

</style>